<template>
  <div v-loading="loading" class="setting-container">
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <span>角色管理</span>
      </div>
      <!-- 卡片内容 -->
      <!-- v-model是绑定默认页面显示第几个选项卡的内容 -->
      <el-tabs v-model="activeName" @click.native="comIndex">
        <el-tab-pane label="角色管理" name="first">
          <!-- 顶部按钮 -->
          <el-button icon="el-icon-plus" size="small" type="primary" @click="addThis">新增角色</el-button>
          <!-- 角色列表 -->
          <!-- :data是动态绑定 表格里的内容 -->
          <el-table :data="list">
            <!-- type="index"表示自增 -->
            <!-- type是自动设置序序号（分页会重置） ：index是自定义一个序号 会自动传入索引值参数 需要设置形参接收（防止分页重置） -->
            <el-table-column type="index" :index="handleIndex" label="序号" width="100" />
            <!-- prop是绑定data() 里面的数据 -->
            <el-table-column label="角色名称" width="240" prop="name" />
            <el-table-column label="描述" prop="description" />
            <el-table-column label="操作">
              <!-- 通过作用域插槽 获取到表格中的详细数据 -->
              <template v-slot="scope">
                <!-- 标签之前的内容就是插槽的内容 -->
                <el-button size="small" type="success" @click.native="assignAuth(scope.row.id)">分配权限</el-button>
                <el-button size="small" type="primary" @click.native="handleEdit(scope.row.id)">编辑</el-button>
                <!-- 携带表格条数的id值 传给服务器进行删除 -->
                <el-button size="small" type="danger" @click="handleDelete(scope.row.id)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
          <!-- 分页条 -->
          <!-- sizes, prev, pager, next, jumper, ->, total, slot -->
          <!-- slot可以使你在分页栏中自定义内容：通过插槽处理 -->
          <!-- :total是动态绑定 分页页码 根据服务器返回数据的总条数来设置 -->
          <!-- :page-size 是获取规定的分页条数 动态显示页码 -->
          <!-- :current-page 设置页码 获取页码里面的分页条数 -->
          <!-- @current-change 当分页组件发生页码变化时 自动触发 动态切换到相应页码中的分页内容(自带当前页码的参数 需要设置形参接收) -->
          <!-- layout是小组件 prev是上一页按钮 pager是页码 next是下一页按钮 jumper是跳转到页码  slot是自定义(span标签设置 常设置空格) ->是右侧显示的内容 total是总页数 -->
          <el-pagination background :current-page="filterParams.page" :total="total" :page-size="filterParams.pagesize" layout="prev, pager, next, jumper, slot,->, total" @current-change="handleCurrentChange" />
        </el-tab-pane>
        <!-- 公司信息 -->
        <el-tab-pane label="公司信息" name="second">
          <!-- 警告信息 -->
          <el-alert title="对公司名称、公司地址、营业执照、公司地区的更新，将使得公司资料被重新审核，请谨慎修改" type="info" show-icon :closable="false" />
          <!-- 表单 -->
          <el-form label-width="120px" style="margin-top:50px">
            <el-form-item label="公司名称">
              <el-input v-model="companyInfo.name" disabled style="width:400px" />
            </el-form-item>
            <el-form-item label="公司地址">
              <el-input v-model="companyInfo.companyAddress" disabled style="width:400px" />
            </el-form-item>
            <el-form-item label="邮箱">
              <el-input v-model="companyInfo.mailbox" disabled style="width:400px" />
            </el-form-item>
            <el-form-item label="备注">
              <el-input v-model="companyInfo.remarks" type="textarea" :rows="3" disabled style="width:400px" />
            </el-form-item>
          </el-form>
        </el-tab-pane>
      </el-tabs>
    </el-card>
    <!-- 添加角色弹出层 -->
    <!-- sync 动态切换 弹层标题的显示与隐藏 -->
    <!-- 设置判断 如果form表单中存在id 那就是修改页面(修改数据需要id) 否则就是 添加页面(添加页面不需要id) -->
    <el-dialog :title="classSw" :visible.sync="isShowAddBox" @close="off">
      <!-- 在 el-form 标签上面绑定效验  饿了么ui 基于第三方包 提供的效验方法 -->
      <!-- 在el-form 标签上设置 ref直接操作dom节点 进行判断 是否满足效验条件 并且上传成功后 清除输入的数据 -->
      <!-- 一、动态绑定效验三部曲 1. 需要绑定:rules 自定义效验的规则 2. 需要绑定:model 获取data()用户输入的数 3. 给里输入的内容 绑定v-model和prop -->
      <el-form ref="roleForm" :rules="rules" :model="form" label-width="100px">
        <!-- 二、el-form-item 绑定自定义效验规则 -->
        <el-form-item label="角色名称" prop="name">
          <!-- 三、v-model双向绑定 用户输入的内容去效验规则 -->
          <el-input v-model="form.name" placeholder="请输入角色名称" />
        </el-form-item>
        <el-form-item label="角色描述" prop="description">
          <el-input v-model="form.description" placeholder="请输入角色描述" />
        </el-form-item>
      </el-form>
      <!-- 操作按钮 -->
      <!-- 饿了么ui提供的具名插槽 -->
      <template #footer>
        <!-- 添加取消按钮 关闭弹窗 -->
        <el-button @click.native="off">取消</el-button>
        <!-- type是设置按钮样式的 设置提交按钮 -->
        <el-button type="primary" @click.native="addclass">确认</el-button>
      </template>
    </el-dialog>
    <!-- 给角色分配权限弹窗 -->
    <!-- 分配权限的弹层 -->
    <el-dialog title="分配权限" :visible.sync="showAuthDialog" @open="loadAuthList">
      <!-- :data是绑定获取到的数 -->
      <!-- :props是绑定树形结构 label是主树形的属性值(名称) children是子树形的属性值(名称) -->
      <!-- show-checkbox 添加勾选框 -->
      <!-- node-key="id" 每个树节点用来作为唯一标识的属性，整棵树应该是唯一的 node-key是数据跟:data中绑定的一致 (必须添加) -->
      <!-- :default-checked-keys 是默认勾选的节点的 key 的数组 用于获取到用户勾选信息 同步到页面上 -->
      <!-- :check-strictly 在显示复选框的情况下，是否严格的遵循父子不互相关联的做法，默认为 false -->
      <!-- :default-expand-all 是否展开树形结构 默认是true -->
      <el-tree ref="tree" v-loading="loading" :props="defaultProps" :data="permissionData" show-checkbox node-key="id" :default-checked-keys="auths" :check-strictly="true" :default-expand-all="true" />
      <template #footer>
        <div style="text-align: right;">
          <el-button @click="close">取消</el-button>
          <el-button type="primary" @click="handleSubmit">确定</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script>
import { mapState } from 'vuex'
import { reqAssignPerm, reqGetRoleList, reqDeleteRole, reqAddRole, reqGetRoleDetail, reqUpdateRole, reqGetCompanyInfo } from '../../api/setting'
import { reqGetPermissionList } from '../../api/permisson'
import { translateData } from '../../utils/index'
export default {
  name: 'Setting',
  data () {
    return {
      // 加载效果状态位
      loading: false,
      // 角色拥有的权限
      auths: [],
      // props设置数据
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      // 存储权限数据
      permissionData: [],
      // 记录正在操作的角色
      ruleId: '',
      // 设置显示隐藏的状态位
      showAuthDialog: false,
      // 储存获取到的公司信息
      companyInfo: {},
      // 储存添加的数据信息
      form: {
        name: '',
        description: ''
      },
      // 设置表单验证规则
      rules: {
        name: [ // required是必填项目 trigger是事件监听
          { required: true, message: '请输入角色名称', trigger: ['blur', 'change'] }
        ]
      },
      // 控制添加角色的弹窗
      isShowAddBox: false,
      // 绑定默认页面显示第几个选项卡的内容
      activeName: 'first',
      // 设置分页调用接口的参数'
      // 根据页数 页码 设置分页
      filterParams: {
        // 页码
        page: 1,
        // 分页条
        pagesize: 5
      },
      // 储存服务器根据分页获取的数据
      list: [],
      // 设置列表数据的综合
      total: 0
    }
  },
  computed: {
    classSw () {
      return this.form.id ? '修改页面' : '添加页面'
    },
    // 获取Vuex里面的数据
    ...mapState('user', ['userInfo'])
  },
  created () {
    // 声明周期 页面打开时候 调用分页数据
    this.loadRoleList()
  },
  methods: {
    //
    addThis () {
      this.isShowAddBox = true
    },
    // 上传权限
    async handleSubmit () {
      // 分配权限的提交动作
      const ret = await reqAssignPerm({
        // 1、需要分配权限的角色id
        id: this.ruleId,
        // 2、重新选中的权限节点的ids
        permIds: this.$refs.tree.getCheckedKeys()
      })
      if (ret.code === 10000) {
        // 授权成功，关闭弹窗
        this.showAuthDialog = false
      } else {
        this.$message.error(ret.message)
      }
    },
    // 获取权限数据
    loadAuthList () {
      // 加载角色的权限数据
      this.loading = true
      try {
        // 获取所有的权限列表
        const allAuth = reqGetPermissionList()
        // ---------------------------------------
        // 获取角色本来拥有的权限列表
        const roleAuth = reqGetRoleDetail(this.ruleId)
        // 基于Promise的all方法并发的触发两个任务
        Promise.all([allAuth, roleAuth]).then(results => {
          this.permissionData = translateData(results[0].data, '0')
          // el-tree组件的default-checked-keys树形的值是节点的id组成的数组，用于选中节点。
          this.auths = results[1].data.permIds
          // this.$nextTick(() => {
          //   // 保证整个树完成渲染后，再控制节点的选中
          //   this.$refs.tree.setCheckedKeys(this.auths)
          // })
          console.log(this.permissionData)
          console.log(this.ruleId)
          this.loading = false
        })
      } catch {
        this.$message.error('获取权限列表失败')
        this.loading = false
      }
    },
    // 关闭弹窗
    close () {
      this.showAuthDialog = false
    },
    // 设置分配权限的弹窗
    assignAuth (id) {
      this.showAuthDialog = true
      this.ruleId = id
      console.log(this.ruleId)
    },
    // 设置修改按钮点击事件
    async handleEdit (id) {
      // 把弹窗状态位设置为true
      this.isShowAddBox = true
      // 携带id值 获取相应的数据
      const ret = await reqGetRoleDetail(id)
      // 获取服务器的数据 储存到form里面 打印到页面上
      this.form = ret.data
    },
    // 设置关闭按钮
    off () {
      // 关闭弹窗
      this.isShowAddBox = false
      // 清空输入的内容(饿了么ui提供方法) 必须要prop绑定效验规则 才能生效
      this.$refs.roleForm.resetFields()
      // this.$options.data()可以获取data中的所有初始数据
      // 左侧是赋值初始化后的数据 右侧是进行初始化 如果不赋值给原数据 初始化组件关闭后就失效
      this.form = this.$options.data().form
    },
    // 向服务器添加数据
    async addclass () {
      // 进行表单验证 需要直接操作dom节点进行效验(饿了么ui提供) this.$refs.ref设置的名称.validate(item=>{判断item})
      this.$refs.roleForm.validate(async item => {
        // 如果效验不通过 直接return跳出
        if (!item) return
        // 如果验证通过 判断form里面是否存在id 如果存在说明是修改上传 不存在说明是添加数据
        if (this.form.id) { // 如果id存在 说明是修改数据
          try {
            // 携带修改后的form里面的数据 上传到服务器
            const ret = await reqUpdateRole(this.form)
            // 携带form表单里面的数据 上传到服务器 进行修改
            if (ret.code === 10000) {
              // 添加成功，关闭弹窗
              this.isShowAddBox = false
              // 上传成功后 清空输入的内容(饿了么ui提供方法) 必须要prop绑定效验规则 才能生效
              this.$refs.roleForm.resetFields()
              // 重新刷新列表
              this.loadRoleList()
            } else { // 非服务器问题的上传失败
              this.$message.error('修改数据失败')
            }
          } catch (error) { // 网络问题打印服务器返回的数据
            this.$message.error('ret.message')
          }
        } else {
          try {
            // 携带添加后的form里面的数据 上传到服务器
            const ret = await reqAddRole(this.form)
            if (ret.code === 10000) { // 如果添加成功
              // 添加成功，关闭弹窗
              this.isShowAddBox = false
              // 上传成功后 清空输入的内容(饿了么ui提供方法) 必须要prop绑定效验规则 才能生效
              this.$refs.roleForm.resetFields()
              // 重新刷新列表
              this.loadRoleList()
            } else { // 非服务器问题的上传失败
              this.$message.error(ret.message)
            }
          } catch (error) { // 网络问题打印服务器返回的数据
            this.$message.error('ret.message')
          }
        }
      })
    },
    // 获取分页数据
    async loadRoleList () {
      this.loading = true
      // 根据页数 页码 获取分页数据
      const ret = await reqGetRoleList(this.filterParams)
      // 把获取的分页数据 储存起来
      this.list = ret.data.rows
      // 获取总列表数据
      this.total = ret.data.total
      this.loading = false
    },
    // 设置 当分页组件发生页码变化时 自动触发 设置形参 接收传来的当前页面 实现切换效果
    handleCurrentChange (page) {
      // 赋值给页码
      this.filterParams.page = page
      // 把赋值后的页码 上传到服务器 获取当前页码的数据(服务器根据页码返回相应分页数据)
      this.loadRoleList()
    },
    // 计算表格的索引值
    handleIndex (index) { // 接收传来的索引值
      // 动态计算累加的索引
      // (当前页码 - 1) * 每页的条数
      return (this.filterParams.page - 1) * this.filterParams.pagesize + index + 1
      // 动态计算累加的索引
      // (当前页码 - 1) * 每页的条数
      // const { page, pagesize } = this.filterParams
      // return (page - 1) * pagesize + 1 + index
    },
    handleDelete (id) {
      // 删除前进行提示
      this.$confirm('确认要删除角色吗？, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        // 点击确定
        const ret = await reqDeleteRole(id)
        // 删除角色成功，刷新列表
        if (ret.code === 10000) {
          // 判断如果删除完毕后 当前页码没有条数
          if (this.list.length === 1 && this.filterParams.page > 1) {
            this.filterParams.page -= 1
          }
          this.loadRoleList()
        } else {
          // 提示用户删除失败 如果后端返回的是其他数值 不是删除的状态码10000 则打印后端返回的内容(非网络错误)
          this.$message.error(ret.message)
        }
      }).catch((err) => { // 如果是网络问题 删除失败 提示用户
        if (err !== 'cancel') { // 需要排除 取消按钮进入catch行为(点击取消会进入catch 需要判断 排除这个删除失败)
          // 点击取消
          this.$message.error('删除角色失败')
        }
      })
    },
    // 获取公司详细信息
    async comIndex () {
      // 进行判断 如果里面已经有数据了 就不访问服务器获取公司数据了
      if (this.companyInfo.name) return
      try {
        // 获取服务器里面的公司数据
        const ret = await reqGetCompanyInfo(this.userInfo.companyId)
        if (ret.code === 10000) {
          // 把获取到公司的数据 存到数组中
          this.companyInfo = ret.data
        } else {
          // 点击取消
          this.$message.error('获取数据失败了')
        }
      } catch (error) {
        // 点击取消
        this.$message.error('获取数据失败了')
      }
    }
  }
}
</script>
<style lang="sass" scoped>
.el-pagination
  margin-top: 20px
</style>
